/**
 * 高阶函数
 *    概念：一个函数接受一个函数做为参数，返回一个新函数。
 *
 * 高阶组件（Higer-Order Component, HOC）
 *    概念：本质上还是一个函数，该函数接收一个组件做为参数，返回一个新组件
 *
 *    语法：
 *        const NewComponent = fn(WrappedComponent)
 *        fn - 就是高阶组件
 *        WrappedComponent - 需要被包装的组件
 *        NewComponent - 返回的一个新组件
 *
 *    例子：
 *      实现一个高阶组件，用于将组件延迟3秒后再显示
 *
 *    注意事项：
 *      1. 要将props数据透传到被包装的组件上。
 *
 */

import React from "react";

// 定义一个高阶组件
function delayLoad(WrappedComponent, isNeed) {
  // 返回一个组件
  return class DelayLoadComponent extends React.Component {
    state = {
      isLoad: isNeed ? false : true, // 用于表示3秒延迟是否完成
    };

    componentDidMount() {
      setTimeout(() => {
        this.setState({
          isLoad: true,
        });
      }, 3000);
    }

    render() {
      console.log("DelayLoadComponent render", this.props);
      const { isLoad } = this.state;
      // 将我收到的props透传到被包装的组件上
      return isLoad ? (
        // <WrappedComponent name={this.props.name} age={this.props.age} />
        <WrappedComponent {...this.props} />
      ) : (
        <div>加载中...</div>
      );
    }
  };
}

class Hello extends React.Component {
  render() {
    return (
      <div>
        <h4>
          Hello - {this.props.name} - {this.props.age} - {this.props.sex}
        </h4>
      </div>
    );
  }
}

class World extends React.Component {
  render() {
    return (
      <div>
        <h4>World</h4>
      </div>
    );
  }
}

// 调用高阶组件
const NewHello = delayLoad(Hello, true);
const NewWorld = delayLoad(World, false);

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>App</h1>
        <Hello name="张三" age="18" sex="男" />

        <NewHello name="张三" age="18" sex="男" />
        <NewWorld />
      </div>
    );
  }
}

export default App;
